﻿using System.Collections.Generic;
using System.Security.AccessControl;
using System.Linq;
using System.Text;

namespace System.IO
{
    internal class InMemoryDirectoryAccessor : DirectoryAccessorBase
    {
        private static string _currenDirectory;

        private readonly InMemoryFileSystemStore _store;

        public InMemoryDirectoryAccessor(InMemoryFileSystemStore store)
        {
            _store = store;
        }

        public override IDirectoryInfo GetParent(string path)
        {
            return _store.GetDirectoryInfo(LongPathTools.Instance.GetParentDirectory(path));
        }

        public override IDirectoryInfo CreateDirectory(string path, DirectorySecurity directorySecurity)
        {
            if (directorySecurity != null) throw new NotImplementedException();
            return _store.CreateDirectory(path);
        }

        public override bool Exists(string path)
        {
            var directoryInfo = _store.GetDirectoryInfo(path);
            return directoryInfo.Exists;
        }

        public override void SetCreationTimeUtc(string path, DateTime creationTimeUtc)
        {
            var directoryInfo = _store.GetDirectoryInfo(path);
            directoryInfo.CreationTimeUtc = creationTimeUtc;
        }

        public override DateTime GetCreationTimeUtc(string path)
        {
            var directoryInfo = _store.GetDirectoryInfo(path);
            return directoryInfo.CreationTimeUtc;
        }

        public override void SetLastWriteTimeUtc(string path, DateTime lastWriteTimeUtc)
        {
            var directoryInfo = _store.GetDirectoryInfo(path);
            directoryInfo.LastWriteTimeUtc = lastWriteTimeUtc;
        }

        public override DateTime GetLastWriteTimeUtc(string path)
        {
            var directoryInfo = _store.GetDirectoryInfo(path);
            return directoryInfo.LastWriteTimeUtc;
        }

        public override void SetLastAccessTimeUtc(string path, DateTime lastAccessTimeUtc)
        {
            var directoryInfo = _store.GetDirectoryInfo(path);
            directoryInfo.LastAccessTimeUtc = lastAccessTimeUtc;
        }

        public override DateTime GetLastAccessTimeUtc(string path)
        {
            var directoryInfo = _store.GetDirectoryInfo(path);
            return directoryInfo.LastAccessTimeUtc;
        }

        public override DirectorySecurity GetAccessControl(string path, AccessControlSections includeSections)
        {
            throw new NotImplementedException();
        }

        public override void SetAccessControl(string path, DirectorySecurity directorySecurity)
        {
            throw new NotImplementedException();
        }

        public override IEnumerable<string> EnumerateDirectories(string path, string searchPattern, SearchOption searchOption)
        {
            return _store.GetSubdirectories(path, searchOption)
                .Select(t => t.FullName)
                .Where(t => t.MatchesWildcard(searchPattern));
        }

        public override IEnumerable<string> EnumerateFiles(string path, string searchPattern, SearchOption searchOption)
        {
            return _store.GetFiles(path, searchOption)
                .Select(t => t.FullName)
                .Where(t => t. MatchesWildcard(searchPattern));
        }

        public override IEnumerable<string> EnumerateFileSystemEntries(string path, string searchPattern, SearchOption searchOption)
        {
            return _store.GetFileSystemEntries(path, searchOption)
                .Select(t => t.FullName)
                .Where(t => t.MatchesWildcard(searchPattern));            
        }

        public override string[] GetLogicalDrives()
        {
            return _store.GetLogicalDrives();
        }

        public override string GetDirectoryRoot(string path)
        {
            return LongPathTools.Instance.GetPathRoot(path);
        }

        public override string GetCurrentDirectory()
        {
            return _currenDirectory;
        }

        public override void SetCurrentDirectory(string path)
        {
            _currenDirectory = path;
        }

        public override void Move(string sourceDirName, string destDirName)
        {
            _store.MoveDirectory(sourceDirName, destDirName);
        }

        public override void Delete(string path, bool recursive)
        {
            _store.DeleteDirectory(path, recursive);
        }
    }
}